package ycl.base.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import ycl.base.entity.UserFiles;
import ycl.base.mapper.UserFilesMapper;
import ycl.base.req.UserFilesReq;
import ycl.base.res.UserFilesRes;
import ycl.base.service.UserFilesService;
import ycl.base.thread.FileCopyThread;
import ycl.base.utils.UploadFileData;
import ycl.base.utils.UploadFileUtil;
import ycl.common.base.service.impl.BaseServiceImpl;
import ycl.common.result.REnum;
import ycl.common.exception.CustomException;
import ycl.common.models.req.IdNameReq;
import ycl.common.utils.AnnotationUtil;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 用户文件管理 服务实现层
 *
 * @author ycl
 * @date 2022/7/6 0006 11:47:02
 */
@Service
@Slf4j
public class UserFilesServiceImpl extends BaseServiceImpl
		<UserFilesMapper, UserFiles, UserFilesReq, UserFilesRes>
		implements UserFilesService {

	@Resource
	private UserFilesMapper userFilesMapper;


	@Override
	public Page<UserFilesRes> pageList(HttpServletRequest request, UserFiles userFiles, Class<UserFilesRes> c) {
		Long userId = getUserId(request);
		userFiles.setUserId(userId);
		return super.pageList(request, userFiles, c);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void upload(Long userId, UploadFileData uploadData, MultipartFile file) {
		String filename = uploadData.getFilename();
		String userOutPath = uploadData.getUserOutPath();
		save(userId, uploadData);
		//上传文件
		UploadFileUtil.uploadFile(file, userOutPath, filename);
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public void saveAndCopyToUserFold(Long userId, UploadFileData data) {
		save(userId, data);
		String publicOutPath = data.getPublicOutPath();
		String fileUuidName = data.getFileUuidName();
		String src = publicOutPath + fileUuidName;
		new FileCopyThread(src, data.getUserOutPath(), data.getFilename()).start();
	}

	@Transactional(rollbackFor = Exception.class)
	public void save(Long userId, UploadFileData uploadData) {
		if (userId == null || uploadData == null) {
			log.error("UserFilesServiceImpl . upload . exception");
			log.error("userId === {}, uploadData === {}", userId, JSONObject.toJSONString(uploadData));
			throw new CustomException(REnum.CUSTOM_FILE_UPLOAD_EXCEPTION);
		}
		Long size = uploadData.getFileSize();
		String filename = uploadData.getFilename();
		String userOutPath = uploadData.getUserOutPath();
		String suffix = uploadData.getSuffix();
		UserFiles files = new UserFiles()
				.setUserId(userId)
				.setName(filename)
				.setSuffix(suffix)
				.setCrypto(uploadData.getCrypto())
				.setFileSize(size)
				.setPath(userOutPath)
				.setCreateTime(LocalDateTime.now())
				.setDelTime(LocalDateTime.now());
		userFilesMapper.insert(files);
	}


	@Override
	@Transactional(rollbackFor = Exception.class)
	public void rename(HttpServletRequest request, IdNameReq req) {
		Long userId = getUserId(request);
		Long id = req.getId();
		String tableName = AnnotationUtil.getTableName(UserFiles.class);
		UserFiles userFiles = userFilesMapper.selectByIdUserId(id, userId, tableName);
		Assert.notNull(userFiles, "未找到文件");

		String path = userFiles.getPath();
		File oldFile = new File(path, userFiles.getName());
		Assert.isTrue(oldFile.exists(), "该文件不存在, 请检查是否已删除或移动");

		String newName = req.getName();
		File newFile = new File(path, newName);
		Assert.isFalse(newFile.exists(), "该文件名已存在");

		boolean b = oldFile.renameTo(newFile);//重命名
		Assert.isTrue(b, "文件重命名失败, 请重试");

		UserFiles update = new UserFiles();
		update.setName(newName)
				.setId(id);
		userFilesMapper.updateById(update);
	}

	@Override
	public void deleteBatchIds(HttpServletRequest request, List<Long> ids) {
		Long userId = getUserId(request);
		List<UserFiles> list = userFilesMapper.selectBatchIdsUserId(ids, userId);
		if (CollUtil.isEmpty(list))
			return;
		List<Long> deleteIds = new ArrayList<>();
		list.forEach(v -> {
			File file = new File(v.getPath(), v.getName());
			if (!file.exists())
				return;
			deleteIds.add(v.getId());
			file.delete();
		});
		userFilesMapper.userDeleteFilesById(deleteIds);
	}
}
